﻿using Sys.Workflow.Engine.Delegate;
using Sys.Workflow.Engine.Delegate.Events;
using Sys.Workflow.Engine.Delegate.Events.Impl;
using Sys.Workflow.Engine.Impl.Bpmn.Helper;
using Sys.Workflow.Engine.Impl.Cfg;
using Sys.Workflow.Engine.Impl.Persistence.Entity;
using Sys.Workflow.Engine.Tasks;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Sys.Workflow.Engine.impl.util
{
    public class TaskHelper
    {
        public static void ChangeTaskAssignee(ITaskEntity taskEntity, String assignee)
        {
            if ((taskEntity.Assignee != null && !taskEntity.Assignee.Equals(assignee))
                    || (taskEntity.Assignee == null && assignee != null))
            {

                ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.GetProcessEngineConfiguration();
                processEngineConfiguration.TaskService.SetAssignee(taskEntity.Id, assignee);
                FireAssignmentEvents(taskEntity);

                if (taskEntity.Id != null)
                {
                    AddAssigneeIdentityLinks(taskEntity);
                }
            }
        }

        public static void AddAssigneeIdentityLinks(ITaskEntity taskEntity)
        {
            if (taskEntity.Assignee == null)
            {
                return;
            }
            ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.GetProcessEngineConfiguration();

            processEngineConfiguration.TaskService.AddUserIdentityLink(taskEntity.Id, taskEntity.Assignee, IdentityLinkType.ASSIGNEE);

        }

        protected static void FireAssignmentEvents(ITaskEntity taskEntity)
        {
            ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.GetProcessEngineConfiguration();
            try
            {
                processEngineConfiguration.ListenerNotificationHelper.ExecuteTaskListeners(taskEntity, BaseTaskListenerFields.EVENTNAME_ASSIGNMENT);
            }
            catch (BpmnError e)
            {
                ErrorPropagation.PropagateError(e, CommandContextUtil.GetExecutionEntityManager().FindById<IExecutionEntity>(taskEntity.ExecutionId));
            }

            IActivitiEventDispatcher eventDispatcher = processEngineConfiguration.EventDispatcher;
            if (eventDispatcher != null && eventDispatcher.Enabled)
            {
                eventDispatcher.DispatchEvent(ActivitiEventBuilder.CreateEntityEvent(ActivitiEventType.TASK_ASSIGNED, taskEntity));//,processEngineConfiguration.GetEngineCfgKey());
            }
        }

        public static void ChangeTaskOwner(ITaskEntity taskEntity, String owner, ITaskService taskService)
        {
            if ((taskEntity.Owner != null && !taskEntity.Owner.Equals(owner))
                    || (taskEntity.Owner == null && owner != null))
            {

                taskService.SetOwner(taskEntity.Id, owner);

                if (taskEntity.Id != null)
                {
                    AddOwnerIdentityLink(taskEntity, taskService);
                }
            }
        }

        protected static void AddOwnerIdentityLink(ITaskEntity taskEntity, ITaskService taskService)
        {
            if (taskEntity.Owner == null)
            {
                return;
            }
            taskService.AddUserIdentityLink(taskEntity.Id, taskEntity.Owner, IdentityLinkType.OWNER);
        }
    }
}
